package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.apis.article.ArticleFeign;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.exception.CustomException;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.wemedia.builder.ArticleDtoBuilder;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {

    @Autowired
    private WmNewsMapper wmNewsMapper;

    @Autowired
    private WmUserMapper wmUserMapper;

    @Autowired
    private WmChannelMapper wmChannelMapper;

    @Autowired
    private ArticleFeign articleFeign;//同步数据

    @Autowired
    private GreenTextScan greenTextScan;//阿里云api

    @Autowired
    private GreenImageScan greenImageScan;//审核图片

    @Autowired
    private FileStorageService fileStorageService;//上传下载文件


    /**
     * 自媒体文章自动审核
     *
     * @param id 自媒体文章id
     */
    @Override
    @Async //异步调用
    public void autoScanWmNews(Integer id) throws Exception {
        //根据文章id查询文章数据
        WmNews wmNews = wmNewsMapper.selectById(id);
        //判断文章是否被删除
        if (wmNews == null) {//为空代表被删除就抛出异常
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //判断文章状态
        if (wmNews.getStatus().equals(WmNews.Status.SUBMIT.getCode())) {//为待审核才执行自动审核
            //解析得到文章的文本内容和图片内容
            Map<String, Object> data = handleTextAndImages(wmNews);

            //把文本内容上传到阿里云审核
            Boolean flag = handleTexScan(data.get("text").toString(), wmNews);
            if (!flag) {//文本审核失败直接返回
                return;
            }
            //成功继续把图片上传到阿里云进行审核
            flag = handleImageScan((List<String>) data.get("images"), wmNews);
            if (!flag) {//图片审核失败直接返回
                return;
            }
            //都通过把自媒体文章同步到app端
            ResponseResult result = saveAppArticle(wmNews);
            if (!result.getCode().equals(200)) {//如果返回的状态不是200
                //就抛出异常
                throw new CustomException(AppHttpCodeEnum.TRANSF_DATA_FRAIL);
            }
            //修改自媒体文章的状态为9
            wmNews.setArticleId(Long.parseLong(result.getData().toString()));
            updateWmNews(wmNews, (short) 9, "审核成功");
        }
    }

    /**
     * 把数据同步到文章微服务
     *
     * @param wmNews
     * @return
     */
    private ResponseResult saveAppArticle(WmNews wmNews) {
/*        ArticleDto dto = new ArticleDto();
        BeanUtils.copyProperties(wmNews, dto);

        //文章的布局
        dto.setLayout(wmNews.getType());
        dto.setCreatedTime(new Date());

        //封装作者信息
        if (wmNews.getUserId() != null) {
            dto.setAuthorId(wmNews.getUserId().longValue());
            WmUser wmUser = wmUserMapper.selectById(wmNews.getUserId());
            dto.setAuthorName(wmUser.getName());
        }

        //封装频道数据
        if (wmNews.getChannelId() != null) {
            WmChannel wmChannel = wmChannelMapper.selectById(wmNews.getChannelId());
            dto.setChannelName(wmChannel.getName());
        }

        //设置文章id
        if (wmNews.getArticleId() != null) {
            dto.setId(wmNews.getArticleId());
        }*/
        ArticleDtoBuilder builder = new ArticleDtoBuilder(wmNews, wmUserMapper, wmChannelMapper);
        ArticleDto dto = builder
                .buildBeanCopy()
                .buildAuthor()
                .buildChannel()
                .buildBasic()
                .builder();

        ResponseResult responseResult = articleFeign.saveArticle(dto);
        return responseResult;
    }

    /**
     * 审核图片
     *
     * @param images
     * @param wmNews
     * @return
     */
    private Boolean handleImageScan(List<String> images, WmNews wmNews) throws Exception {
        Boolean flag = Boolean.TRUE;
        if (images == null && images.size() == 0) {
            return flag;
        }
        //对图片去重
        images = images.stream().distinct().collect(Collectors.toList());
        //下载图片
        List<byte[]> imagesList = new ArrayList<>(images.size());
        for (String url : images) {
            byte[] bytes = fileStorageService.downLoadFile(url);
            imagesList.add(bytes);
        }

        Map map = greenImageScan.imageScan(imagesList);

        if (map != null) {
            if (map.get("suggestion").equals("block")) {
                flag = Boolean.FALSE;
                updateWmNews(wmNews, (short) 2, "图片中存在违规内容");
            } else if (map.get("suggestion").equals("review")) {
                flag = Boolean.FALSE;
                updateWmNews(wmNews, (short) 3, "图片中存在不确定的内容需要进行人工审核");
            }
        }
        return flag;
    }

    /**
     * 审核文本内容
     *
     * @param text
     * @param wmNews
     * @return
     */
    private Boolean handleTexScan(String text, WmNews wmNews) throws Exception {
        Boolean flag = Boolean.TRUE;
        if (StringUtils.isEmpty(text)) {
            return flag;
        }

        Map map = greenTextScan.greeTextScan(text);
        if (map != null) {
            if (map.get("suggestion").equals("block")) {
                flag = Boolean.FALSE;
                updateWmNews(wmNews, (short) 2, "文本内存中存在违规的内容");
            } else if (map.get("suggestion").equals("review")) {
                flag = Boolean.FALSE;
                updateWmNews(wmNews, (short) 3, "文本内存中存在不确定的内容需要进行人工审核");
            }
        }
        return flag;
    }

    /**
     * 从文章中解析得到文本内容和图片
     *
     * @param wmNews
     * @return
     */
    private Map<String, Object> handleTextAndImages(WmNews wmNews) {
        StringBuilder sb = new StringBuilder();
        List<String> images = new ArrayList<>();
        //处理文本内容
        if (StringUtils.isNotBlank(wmNews.getContent())) {
            List<Map> list = JSON.parseArray(wmNews.getContent(), Map.class);
            for (Map map : list) {
                if ("text".equals(map.get("type").toString())) {
                    sb.append(map.get("value").toString());
                } else {
                    images.add(map.get("value").toString());
                }
            }
        }
        //处理封面
        if (StringUtils.isNotEmpty(wmNews.getImages())) {
            images.addAll(Arrays.asList(wmNews.getImages().split(",")));
        }
        //处理标题内容
        sb.append("-").append(wmNews.getTitle());
        Map<String, Object> map = new HashMap<>();
        map.put("text", sb.toString());
        map.put("images", images);
        return map;
    }

    /**
     * 更新文章的审核状态和审核原因
     *
     * @param wmNews
     * @param status
     * @param reson
     */
    private void updateWmNews(WmNews wmNews, short status, String reson) {
        wmNews.setStatus(status);
        wmNews.setReason(reson);

        wmNewsMapper.updateById(wmNews);
    }
}